package ch.exm.storm.session;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

import ch.exm.storm.query.Query;
import ch.exm.storm.query.QueryFactory;
import ch.exm.storm.query.inmemory.InMemoryQuery;

public class StormSession {
	
	private QueryFactory queryFactory;

	StormSession(QueryFactory queryFactory) {
		this.queryFactory = queryFactory;
	}
	
	public Query createQuery() {
		Query query = queryFactory.createQuery();
		if (query instanceof InMemoryQuery) 
			query = (Query)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Query.class }, new QueryProxy(query));
		return query;
	}
	
	private class QueryProxy implements InvocationHandler {
		private Query query;
		QueryProxy(Query query) { this.query = query; }
		
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			Object result = method.invoke(query, args);
			if (method.getName().equals("doQuery")) {
				if (result instanceof Iterable) result = proxyMultipleQueryResult((Iterable<?>)result);
				else result = proxyQueryResult(result);
			}
			return result;
		}
		
		private Iterable<?> proxyMultipleQueryResult(Iterable<?> results) {
			List<Object> proxiedResults = new ArrayList<Object>();
			for (Object result : results) proxiedResults.add(proxyQueryResult(result));
			return proxiedResults;
		}
		
		private Object proxyQueryResult(Object result) {
			// TODO: proxy the query result
			return null;
		}
	}
}
